# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.930.33.4 -> 1.930.33.5 # drivers/char/Config.in 1.39.1.4 -> 1.39.1.5 # drivers/char/serial.c 1.35 -> 1.36 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/02/24 bjorn_helgaas@hp.com 1.930.33.5 # serial: Add discovery via ACPI namespace. # -------------------------------------------- # diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in --- a/drivers/char/Config.in Wed Oct 8 09:06:54 2003 +++ b/drivers/char/Config.in Wed Oct 8 09:06:54 2003 @@ -24,6 +24,9 @@ tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL fi + if [ "$CONFIG_ACPI" = "y" ]; then + bool ' Support for serial ports defined in ACPI namespace' CONFIG_SERIAL_ACPI + fi fi dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then diff -Nru a/drivers/char/serial.c b/drivers/char/serial.c --- a/drivers/char/serial.c Wed Oct 8 09:06:54 2003 +++ b/drivers/char/serial.c Wed Oct 8 09:06:54 2003 @@ -92,9 +92,8 @@ * ever possible. * * CONFIG_SERIAL_ACPI - * Enable support for serial console port and serial - * debug port as defined by the SPCR and DBGP tables in - * ACPI 2.0. + * Enable support for serial ports found in the ACPI + * namespace. */ #include @@ -222,6 +221,10 @@ #ifdef CONFIG_MAGIC_SYSRQ #include #endif +#ifdef ENABLE_SERIAL_ACPI +#include +#include "../acpi/acpi_bus.h" +#endif /* * All of the compatibilty code so we can compile serial.c against @@ -4658,6 +4661,77 @@ } } +#ifdef ENABLE_SERIAL_ACPI +static acpi_status acpi_serial_resource(acpi_resource *resource, void *data) +{ + struct serial_struct *serial_req = (struct serial_struct *) data; + acpi_resource_address64 addr; + acpi_status status; + + status = acpi_resource_to_address64(resource, &addr); + if (ACPI_SUCCESS(status)) { + serial_req->iomem_base = ioremap(addr.min_address_range, + addr.max_address_range - addr.min_address_range + 1); + serial_req->io_type = SERIAL_IO_MEM; + serial_req->port = 0; + serial_req->port_high = 0; + } else if (resource->id == ACPI_RSTYPE_EXT_IRQ) { + acpi_resource_ext_irq *ext_irq = &resource->data.extended_irq; + if (ext_irq->number_of_interrupts > 0) { + serial_req->irq = acpi_register_irq(ext_irq->interrupts[0], + ext_irq->active_high_low, ext_irq->edge_level); + } + } + + return AE_OK; +} + +static int acpi_serial_add(struct acpi_device *device) +{ + struct serial_struct serial_req; + int line; + + memset(&serial_req, 0, sizeof(serial_req)); + + acpi_walk_resources(device->handle, METHOD_NAME__CRS, + acpi_serial_resource, &serial_req); + + serial_req.baud_base = BASE_BAUD; + serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ; + serial_req.xmit_fifo_size = serial_req.custom_divisor = 0; + serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0; + serial_req.iomem_reg_shift = 0; + + line = register_serial(&serial_req); + if (line < 0) + return -ENODEV; + + return 0; +} + +static int acpi_serial_remove(struct acpi_device *device, int type) +{ + return 0; +} + +static struct acpi_driver acpi_serial_driver = { + name: "serial", + class: "", + ids: "PNP0501", + ops: { + add: acpi_serial_add, + remove: acpi_serial_remove, + }, +}; + +/* + * Look for serial ports in the ACPI namespace. + */ +static void __devinit probe_serial_acpi(void) +{ + acpi_bus_register_driver(&acpi_serial_driver); +} +#endif /* ENABLE_SERIAL_ACPI */ static struct pci_device_id serial_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, @@ -5618,6 +5692,9 @@ tty_register_devfs(&callout_driver, 0, callout_driver.minor_start + state->line); } +#ifdef ENABLE_SERIAL_ACPI + probe_serial_acpi(); +#endif #ifdef ENABLE_SERIAL_PCI probe_serial_pci(); #endif